package com.flyox.game.militarychess.server.business;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.flyox.game.militarychess.CONSTS;
import com.flyox.game.militarychess.bean.ChessDesk;
import com.flyox.game.militarychess.bean.ChessMan;
import com.flyox.game.militarychess.bean.ChessSeat;
import com.flyox.game.militarychess.bean.Player;
import com.flyox.game.militarychess.bean.Position;
import com.flyox.game.militarychess.bean.ChessSeat.SEAT_NAME;
import com.flyox.game.militarychess.bean.ChessSeat.SEAT_STATE;
import com.flyox.game.militarychess.message.BoardBean;
import com.flyox.game.militarychess.message.ChessPackage;
import com.flyox.game.militarychess.message.Response;
import com.flyox.game.militarychess.server.services.DeskService;
import com.flyox.game.militarychess.server.services.LayoutService;
import com.flyox.game.militarychess.server.services.PlayerService;
import com.flyox.game.militarychess.service.ChessService;
import com.flyox.game.militarychess.util.Secret;
import com.flyox.game.militarychess.util.SerialUtil;

public class BroadService {
	private final Logger logger = LoggerFactory.getLogger(getClass());
	PlayerService playerService=new PlayerService();
	DeskService deskService=new DeskService();
	LayoutService layoutService=new LayoutService();
	/**
	 * 完成调度
	 * @param player
	 */
	public void onSeatBroad(Player player) {
		Hashtable<String, Player> players = playerService.getPlayers();
		Enumeration<Player> e = players.elements();
		while (e.hasMoreElements()) {// to all not on seat
			Player p = e.nextElement();
			// 广播给在大厅和同桌，不包括本人
			if (p.getStates() == CONSTS.PLAYER_STATS_LOGIN || ((p.getDeskNum() == player.getDeskNum()) && !(p.getId().equals(player.getId())))) {
				ChessPackage cp = new ChessPackage(CONSTS.CMD_BOARD);
				BoardBean bb = new BoardBean(CONSTS.CMD_BOARD_ONSEAT);
				bb.setChessDesk(deskService.getDesks().get(player.getDeskNum()));
				try {
					byte[] resp = SerialUtil.enSerial(bb);
					resp = Secret.encryptMsg(resp, p.getDesKey());
					cp.setContent(resp);
					if(p.getSession()!=null&&p.getSession().isConnected()){
						p.getSession().write(cp);
					}
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	/**
	 * 完成调度
	 * @param player
	 */
	public void onReady(Player player) {
		logger.info("CMD_BOARD_READY playerid="+player.getName());
		Hashtable<String, Player> players = playerService.getPlayers();
		ChessDesk chessDesk = deskService.getDesks().get(player.getDeskNum());
		Hashtable<SEAT_NAME, ChessSeat> seats = chessDesk.getSeats();
		Enumeration<ChessSeat> s = seats.elements();
		while (s.hasMoreElements()) {
			ChessSeat cs = s.nextElement();
			if (cs.getPlayerID() != null && !player.getId().equals(cs.getPlayerID())) {
				ChessPackage cp = new ChessPackage(CONSTS.CMD_BOARD);
				BoardBean bb = new BoardBean(CONSTS.CMD_BOARD_READY);
				bb.setChessDesk(chessDesk);
				Player boradPlayer = players.get(cs.getPlayerID());
				bb.setLayout(layoutService.getDeskLayout(boradPlayer));
				try {
					byte[] resp = SerialUtil.enSerial(bb);
					resp = Secret.encryptMsg(resp, boradPlayer.getDesKey());
					cp.setContent(resp);
					boradPlayer.getSession().write(cp);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	/**
	 * 吃子请求
	 * @param player
	 * @param response
	 * @param from
	 * @param to
	 */
	public void onEat(Player player, Response response, Position from, Position to) {
		ChessDesk chessDesk = deskService.getChessDesk(player.getDeskNum());
		Hashtable<SEAT_NAME, ChessSeat> seats = chessDesk.getSeats();
		Enumeration<ChessSeat> s = seats.elements();
		while (s.hasMoreElements()) {
			ChessSeat cs = s.nextElement();
			if (cs.getPlayerID() != null && !player.getId().equals(cs.getPlayerID())) {
				ChessPackage cp = new ChessPackage(CONSTS.CMD_BOARD);
				BoardBean bb = new BoardBean(CONSTS.CMD_BOARD_EAT);
				Player boradPlayer = playerService.getPlayer(cs.getPlayerID());
				bb.setLayout(layoutService.getDeskLayout(boradPlayer));
				bb.setChessManStates(response.getChessManStates());// 吃子后棋子状态
				bb.setSeatStates(response.getSeatStates());
				bb.setTeamStates(response.getTeamStates());
				bb.setChessDesk(chessDesk);
				bb.setFrom(from);
				bb.setTo(to);

				// 个人状态
				// 队伍状态
				try {
					byte[] resp = SerialUtil.enSerial(bb);
					resp = Secret.encryptMsg(resp, boradPlayer.getDesKey());
					cp.setContent(resp);
					boradPlayer.getSession().write(cp);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
	/**
	 * 走棋
	 * @param player
	 * @param response
	 * @param from
	 * @param to
	 */
	public void onMove(Player player, Position from, Position to) {
		ChessDesk chessDesk = deskService.getDesks().get(player.getDeskNum());
		Hashtable<SEAT_NAME, ChessSeat> seats = chessDesk.getSeats();
		Enumeration<ChessSeat> s = seats.elements();
		while (s.hasMoreElements()) {
			ChessSeat cs = s.nextElement();
			if (cs.getPlayerID() != null && !player.getId().equals(cs.getPlayerID())) {
				ChessPackage cp = new ChessPackage(CONSTS.CMD_BOARD);
				BoardBean bb = new BoardBean(CONSTS.CMD_BOARD_MOVE);
				Player boradPlayer = playerService.getPlayer(cs.getPlayerID());
				bb.setLayout(layoutService.getDeskLayout(boradPlayer));
				bb.setChessDesk(chessDesk);
				bb.setFrom(from);
				bb.setTo(to);

				// 个人状态
				// 队伍状态
				try {
					byte[] resp = SerialUtil.enSerial(bb);
					resp = Secret.encryptMsg(resp, boradPlayer.getDesKey());
					cp.setContent(resp);
					boradPlayer.getSession().write(cp);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 投降
	 * @param player
	 * @param response
	 */
	public void onSurrender(Player player, Response response) {
		ChessDesk chessDesk = deskService.getDesks().get(player.getDeskNum());
		Hashtable<SEAT_NAME, ChessSeat> seats = chessDesk.getSeats();
		Enumeration<ChessSeat> s = seats.elements();
		while (s.hasMoreElements()) {
			ChessSeat cs = s.nextElement();
			if (cs.getPlayerID() != null && !player.getId().equals(cs.getPlayerID())) {
				ChessPackage cp = new ChessPackage(CONSTS.CMD_BOARD);
				BoardBean bb = new BoardBean(CONSTS.CMD_BOARD_SURRENDER);
				Player boradPlayer = playerService.getPlayer(cs.getPlayerID());
				bb.setLayout(layoutService.getDeskLayout(boradPlayer));
				bb.setChessDesk(chessDesk);
				bb.setTeamStates(response.getTeamStates());
				// 个人状态
				// 队伍状态
				try {
					byte[] resp = SerialUtil.enSerial(bb);
					resp = Secret.encryptMsg(resp, boradPlayer.getDesKey());
					cp.setContent(resp);
					if(boradPlayer.getSession()!=null&&boradPlayer.getSession().isConnected()){
						boradPlayer.getSession().write(cp);
					}else{
						//连接断开
					}
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
	
	public void onOverTime(Player player, Response response) {
		ChessDesk chessDesk = deskService.getChessDesk(player.getDeskNum());
		Hashtable<SEAT_NAME, ChessSeat> seats = chessDesk.getSeats();
		Enumeration<ChessSeat> s = seats.elements();
		while (s.hasMoreElements()) {
			ChessSeat cs = s.nextElement();
			if (cs.getPlayerID() != null && !player.getId().equals(cs.getPlayerID())) {
				ChessPackage cp = new ChessPackage(CONSTS.CMD_BOARD);
				BoardBean bb = new BoardBean(CONSTS.CMD_BOARD_OVERTIME);
				Player boradPlayer = playerService.getPlayer(cs.getPlayerID());
				bb.setLayout(layoutService.getDeskLayout(boradPlayer));
				bb.setChessDesk(chessDesk);
				bb.setTeamStates(response.getTeamStates());
				// 个人状态
				// 队伍状态
				try {
					byte[] resp = SerialUtil.enSerial(bb);
					resp = Secret.encryptMsg(resp, boradPlayer.getDesKey());
					cp.setContent(resp);
					if(boradPlayer.getSession()!=null&&boradPlayer.getSession().isConnected()){
						boradPlayer.getSession().write(cp);
					}else{
						//连接断开
					}
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 删除顾客信息
	 * 更改座位状态
	 * @param player
	 */
	public void onLogout(Player player) {
		//Hashtable<String, Player> players = playerService.getPlayers();
		BoardBean bb = new BoardBean(CONSTS.CMD_BOARD_LOGOUT);
		
		ChessDesk chessDesk = deskService.getChessDesk(player.getDeskNum());
		
		if(player.getStates()<CONSTS.PLAYER_STATS_ONSEAT){
			//没有坐下 通知所有人 更新房间状态
			playerService.removePlayer(player.getId());
		}else if(player.getStates()==CONSTS.PLAYER_STATS_PLAYING){//比赛状态
			//更改座位状态
			ChessSeat chessSeat=chessDesk.getSeats().get(player.getSeatName());
			chessSeat.setPlayerID(null);
			chessSeat.setSeatState(SEAT_STATE.EMPTY);
			
			//更新布局
			ChessMan[][] layout = layoutService.getDeskLayout(player);
			for (int i = 0; i < 13; i++) {
				for (int j = 0; j < 20; j++) {
					if (layout[i][j] != null && player.getSeatName().equals(layout[i][j].getTeam())) {
						layout[i][j] = null;
					}
				}
			}
			bb.setLayout(layout);
			
			// 判断是否全局结束
			player.setStates(CONSTS.PLAYER_STATS_FAIL);
			
			int teamRes = new ChessService().getTeamRes(player);
			bb.setTeamStates(teamRes);
			if (teamRes != CONSTS.RESPONSE_EAT_CONTINUE) {
				//TODO clean users
			}
			// 得到下一个走棋的人
			new RequestService().updateOnTurnPlayer(chessDesk);
			bb.setChessDesk(chessDesk);
			
			//
			Hashtable<SEAT_NAME, ChessSeat> seats = chessDesk.getSeats();
			Enumeration<ChessSeat> s = seats.elements();
			while (s.hasMoreElements()) {
				ChessSeat cs = s.nextElement();
				if (cs.getPlayerID() != null && !player.getId().equals(cs.getPlayerID())) {
					ChessPackage cp = new ChessPackage(CONSTS.CMD_BOARD);
					Player boradPlayer = playerService.getPlayer(cs.getPlayerID());
					try {
						byte[] resp = SerialUtil.enSerial(bb);
						resp = Secret.encryptMsg(resp, boradPlayer.getDesKey());
						cp.setContent(resp);
						if(boradPlayer.getSession()!=null&&boradPlayer.getSession().isConnected()){
							boradPlayer.getSession().write(cp);
						}else{
							//连接断开
						}
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}
		}else{//其他状态 以坐下 等待其他人开始 比赛赢
			//更改座位状态
			ChessSeat chessSeat=chessDesk.getSeats().get(player.getSeatName());
			chessSeat.setPlayerID(null);
			chessSeat.setSeatState(SEAT_STATE.EMPTY);
			
			//更新布局
			ChessMan[][] layout = layoutService.getDeskLayout(player.getDeskNum());
			for (int i = 0; i < 13; i++) {
				for (int j = 0; j < 20; j++) {
					if (layout[i][j] != null && player.getSeatName().equals(layout[i][j].getTeam())) {
						layout[i][j] = null;
					}
				}
			}
			bb.setLayout(layout);
			
			// 得到下一个走棋的人
			bb.setChessDesk(chessDesk);
			//
			Hashtable<SEAT_NAME, ChessSeat> seats = chessDesk.getSeats();
			Enumeration<ChessSeat> s = seats.elements();
			while (s.hasMoreElements()) {
				ChessSeat cs = s.nextElement();
				if (cs.getPlayerID() != null && !player.getId().equals(cs.getPlayerID())) {
					ChessPackage cp = new ChessPackage(CONSTS.CMD_BOARD);
					Player boradPlayer = playerService.getPlayer(cs.getPlayerID());
					try {
						byte[] resp = SerialUtil.enSerial(bb);
						resp = Secret.encryptMsg(resp, boradPlayer.getDesKey());
						cp.setContent(resp);
						if(boradPlayer.getSession()!=null&&boradPlayer.getSession().isConnected()){
							boradPlayer.getSession().write(cp);
						}else{
							//连接断开
						}
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}//end while
		}
	}
	
	/**
	 * 广播消息
	 * 
	 * @param player
	 * @param message
	 */
	public void onMessage(Player player, String message) {
		Hashtable<String, Player> players = playerService.getPlayers();
		Enumeration<Player> e = players.elements();
		while (e.hasMoreElements()) {// to all not on seat
			Player p = e.nextElement();
			// 广播给在大厅和同桌，不包括本人
			if (p.getStates() == CONSTS.PLAYER_STATS_LOGIN || ((p.getDeskNum() == player.getDeskNum()) && !(p.getId().equals(player.getId())))) {
				ChessPackage cp = new ChessPackage(CONSTS.CMD_BOARD);
				BoardBean bb = new BoardBean(CONSTS.CMD_BOARD_MESSAGE);
				bb.setMessage(message);
				try {
					byte[] resp = SerialUtil.enSerial(bb);
					resp = Secret.encryptMsg(resp, p.getDesKey());
					cp.setContent(resp);
					p.getSession().write(cp);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
}
